# coding:utf-8

import os, threading, sys, time
from PIL import Image
from PIL import ImageFile

ImageFile.LOAD_TRUNCATED_IMAGES = True
from flask import Flask, render_template, request, redirect, url_for, json

import requests as sys_request

app = Flask(__name__)

from multiprocessing import cpu_count
import threadpool


def thread_pool(enter_func, param_list):
    pool = threadpool.ThreadPool(cpu_count() * 2)
    requests = threadpool.makeRequests(enter_func, param_list)
    [pool.putRequest(req) for req in requests]
    pool.wait()


def do_cvt(file, full_path, out_path, idx):
    try:
        global g_full_num
        global g_processing_num
        g_processing_num = idx
        sys.stdout.write('\r>> processing %d/%d ' % (
            g_processing_num, g_full_num))
        sys.stdout.flush()
        im = Image.open(full_path)
        if os.path.exists(out_path) is False:
            os.makedirs(out_path)
        im.save(os.path.join(out_path, file))
    except Exception as ex:
        print(ex)


def do_cvt_enter(path, out_path='formated'):
    global g_full_num
    out_path = os.path.join(path, out_path)
    param_list = []
    files = os.listdir(path)
    for idx, file in enumerate(files):
        full_path = os.path.join(path, file)
        if os.path.isdir(full_path) is False:
            param_list.append(((file, full_path, out_path, idx + 1), None))
    g_full_num = len(param_list)
    thread_pool(do_cvt, param_list)


def do_agent_request(payload):
    rep = sys_request.post(url=url, data=payload, headers=headers)
    print("imageservice_agent request response {}".format(rep.text))
    sys.stdout.flush()
    rep.encoding = 'utf-8'
    print(rep.text)
    sys.stdout.flush()


def get_files_list(rq_value):
    lists = []
    abs_path = rq_value['objURL']
    global REQUEST_KEY_OFFSET
    num = len(rq_value) - REQUEST_KEY_OFFSET
    for i in range(num):
        lists.append(os.path.join(abs_path, rq_value['files[{}][file]'.format(i)]))
    return lists


def get_xywh(rq_value, real_width, real_height):
    height = real_height
    width = real_width
    x1 = rq_value['x1']
    x2 = rq_value['x2']
    y1 = rq_value['y1']
    y2 = rq_value['y2']
    xc = int((float(x1) + float(x2)) * float(width) / 2)
    yc = int((float(y1) + float(y2)) * float(height) / 2)
    w_car = int((float(x2) - float(x1)) * float(width))
    h_car = int((float(y2) - float(y1)) * float(height))
    return xc, yc, w_car, h_car


def create_trace_json_from_request_value(rq_value):
    dict = {}
    files_list = get_files_list(rq_value)

    if rq_value['trace_type'] == 'trace_in':
        # 进车 ， 最后一张图是起点并 倒着 跟踪 .
        dict['detect_type'] = 'history_backward_recognize'
        files_list.sort()
        files_list.reverse()
        dict['img_path_share'] = files_list[-1]
    else:
        # 出车， 第一张 是起点， 并 顺着 跟踪。
        dict['detect_type'] = 'history_forwward_recognize'
        files_list.sort()
        dict['img_path_share'] = files_list[0]

    dict["SmartParking"] = "192.168.9.253_8000"
    dict['park_area_id'] = 7
    im_width, im_height = Image.open(files_list[0]).size
    dict['img_car_position'] = {
        "height": get_xywh(rq_value, im_width, im_height)[3],
        "width": get_xywh(rq_value, im_width, im_height)[2],
        "x": get_xywh(rq_value, im_width, im_height)[0],
        "y": get_xywh(rq_value, im_width, im_height)[1],
    }
    dict['history_img_path'] = files_list
    return dict


@app.route('/cvt_tool', methods=['POST', 'GET'])
def cvt_tool():
    return render_template('cvt_tool.html')


@app.route('/coordinates', methods=['POST', 'GET'])
def coordinates():
    if request.method == 'POST':
        print('cvt_tool received: {}'.format(request.values))
        info = create_trace_json_from_request_value(request.values)
        # json.dump(info, open("{}.json".format(time.time()), 'w'))
        return json.dumps(info)
    return render_template('cvt_tool.html')


@app.route('/process_status', methods=['POST', 'GET'])
def process_status():
    if request.method == 'POST':
        print('process_status received: {}'.format(request.values))
        info = {}
        global g_processing_num
        global g_full_num
        info['processed'] = g_processing_num
        info['full_num'] = g_full_num

        return json.dumps(info)
    return render_template('cvt_tool.html')


@app.route('/process_start', methods=['POST', 'GET'])
def process_start():
    if request.method == 'POST':
        print('process_start received: {}'.format(request.values))
        info = {}
        try:
            cvt_im_path = request.values['cvt_im_path']
            t = threading.Thread(target=do_cvt_enter, args=(cvt_im_path,))
            t.start()

            info['info'] = 'process started'
            info['status'] = 'success'
        except Exception as ex:
            info['info'] = str(ex)
            info['status'] = 'fail'
            print(str(ex))
        return json.dumps(info)
    return render_template('cvt_tool.html')


@app.route('/imageservice_agent', methods=['POST', 'GET'])
def imageservice_agent():
    if request.method == 'POST':
        payload = request.values['payload']
        print('imageservice_agent received: {}'.format(payload))

        # t = threading.Thread(target=do_agent_request, args=(payload,))
        # t.start()
        # t.join()
        # return rep.text
        do_agent_request(payload)
        return payload

    return render_template('cvt_tool.html')


g_processing_num = 0
g_full_num = 0
# url = 'http://192.168.0.125:40005/imageservice/'
url = 'http://localhost:8080/imageservice/'
# url = 'http://192.168.23.41:40005/imageservice/'
headers = {'Content-Type': 'application/json'}
REQUEST_KEY_OFFSET = 8
if __name__ == '__main__':
    print(" #################################agent:{}".format(url))

    app.run('0.0.0.0', debug=True)

    # TODO: load img to draw pts
